/**
 * 
 */
package com.jolestar.yayaweibotong.task;

import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.appengine.api.labs.taskqueue.Queue;
import com.google.appengine.api.labs.taskqueue.QueueFactory;
import com.google.appengine.api.labs.taskqueue.TaskOptions;
import com.google.appengine.api.labs.taskqueue.TaskOptions.Method;
import com.jolestar.yayaweibotong.service.UserService;

/**
 * @author jolestar@gmail.com
 * 
 */
public abstract class AbstractTask implements Task {

	/**
	 * 
	 */
	private static final long serialVersionUID = 280368956356108077L;

	protected final Logger log = Logger.getLogger(this.getClass().getName());

	protected String name;
	protected UserService userService = UserService.ServiceHolder.getInstance();

	/**
	 * 
	 */
	public AbstractTask(String name) {
		this.name = name;
	}

	public String getName() {
		return this.name;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jolestar.yayaweibotong.task.Task#doTask()
	 */
	@Override
	public boolean run(String uri, Map<String, String> headers,
			Map<String, String> params) {
		log.info(this.name + " task start.");
		long start = System.currentTimeMillis();
		boolean result = true;
		try {
			result = this.doTask(headers, params);
		} catch (Exception e) {
			log.log(Level.SEVERE, e.getMessage(), e);
			result = false;
		}
		log.info(this.name + " task end. use time:"
				+ (System.currentTimeMillis() - start));
		return result;
	}

	protected void retryLatter(Map<String, String> headers,
			Map<String, String> params, long countdownMillis) {
		int retryCount = 0;
		String retryCountStr = headers.get(YAYA_TASK_RETRY_LATTER_COUNT_HEADER);
		if (retryCountStr != null) {
			try {
				retryCount = Integer.parseInt(retryCountStr);
			} catch (Exception e) {
				log.warning(e.getMessage());
			}
		}
		if (retryCount > 5) {
			log.severe("task retryLatterCount >5, give up.");
			return;
		}
		try {
			Queue queue = QueueFactory.getQueue(this.name);
			TaskOptions task = TaskOptions.Builder.method(Method.POST);
			for (Map.Entry<String, String> entry : params.entrySet()) {
				task.param(entry.getKey(), entry.getValue());
			}
			retryCount++;
			task.header(YAYA_TASK_RETRY_LATTER_COUNT_HEADER,
					Integer.toString(retryCount)).countdownMillis(
					countdownMillis);
			queue.add(task);
		} catch (Exception e) {
			log.log(Level.SEVERE, e.getMessage(), e);
		}
	}

	protected abstract boolean doTask(Map<String, String> headers,
			Map<String, String> params);

}
